Vueとwebpackで学ぶCode Splitting
Code Splitting
Code Splittingを利用すると、コードを複数のバンドルに分け、必要に応じて非同期で読み込むことができる
webpackは、複数のファイルを1つのファイルにバンドルし、webページの高速化に貢献している
一方で、すべてを1つのファイルにまとめてしまうと、現在のページでは必要ではないリソースまで読み込むことになる
そこでwebpackの機能であるCode Splittingを利用しバンドルを分割することで、そのページに必要なリソースのみが入ったバンドルを作成することができる
別のページに遷移した場合は、そのページで必要なリソースを非同期読み込む
リソースをバンドルすると、複数のファイルが1つにまとまり、HTTPリクエストを減らす事でページ表示が高速化される
HTTPのリクエスト回数が減るため、ページが高速化される
一方でリクエスト1回あたりの取得リソースサイズは大きくなる
現在のページで必要のないリソースを読み込むため、その分が無駄になる
Code Splitting
コードが分割されるため、1つの大きいファイルが分割されて必要な分だけ読み込まれる
小さいファイルのリクエストが複数回発生するためオーバーヘッドが生じる
1つの巨大なバンドルでも、微小で大量のファイルでも遅くなるため、適切なサイズで分割することが重要
if used correctly, can have a major impact on load time.
今回はVueとwebpackを持ちいてCode Splittingをしてみる
Vue でCode Splitting
Vue CLI3.0ではCode Splitting(コード分割)をサポートしているため導入は非常に簡単
こんな感じのimportを
code: bundle.ts
import ItemPool from "@/components/Organisms/ItemPool.vue";
@Component({
name: "combine-table",
components: {
"item-pool": ItemPool
}
})
こう書くと別Bundleとして分割されるようになる
code: split.ts
@Component({
name: "combine-table",
components: {
"item-pool": () => import("@/components/Organisms/ItemPool.vue")
}
})
分割できるだけ分割したものがこちら
Webpack Bundle Analyzerで可視化する
https://gyazo.com/7378e3806bd203d41d72a4d80103d270 https://gyazo.com/6d496b5a272317d7f98c5fafeb340823
左分割前(合計サイズ487KB) 右分割後 (合計サイズ572KB)
分割する際に、重複する項目が各Bundleに入るためサイズが大きくなっている
分割してみて表示速度はどう変化したか
実際にやってみた。とりあえず分割できるだけ分割してみる。
結果: 分割したら遅くなった!!
速度統計
https://gyazo.com/26b66f09d328c66cd4bf02c434dece1b https://gyazo.com/603ee095ada1f8cc1b2e3d6b9386dd0c
左分割前 右分割後
初回ペイントは分割後の方が多少早くなっているが、速度インデックスとインラタクティブになるまでの時間が壊滅している
コードを分割したため、初回の読み込みは最小限になるが、ページに必要な情報をすべて読み込むまでの時間がかなり伸びている
分割できるだけ分割した(コンポーネント毎にファイルが分割された)ため、小さいファイルが大量に生成された。
それらを取得するために大量のHTTPリクエストが必要になるため、遅くなっている
リクエスト数
https://gyazo.com/60e34c80b14f688f1b7b445b5bee479d https://gyazo.com/6bb5e1e7fa3765695d4c553342ae4f83
左分割前 右分割後
リクエスト数も増加している
その他の項目はあと読みのjsとcssファイル
参考
コードを分割できるだけ分割した場合にはこのようなjsとcssファイルが生成される
https://gyazo.com/c9872330e671c1f30f56cd726e2fe37b
結局どうすればいいのか
はじめに書いた通り、適切なサイズで分割することが重要
適切なサイズってどれぐらいか
・モバイルをターゲットにするなら200kb以下
Chrome開発者ツールのCoverage機能でJavaScriptのうち何割がそのページで使用されているかを確認できる
この割合とjsファイルのサイズを見て判断しても良い
個人的には使用していないコードが150KB以上あったら分割したい
vue routerを使っているならトップレベルの要素だけ分割するのも良さそう
code: router.ts
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: () => import("@/components/Pages/Home.vue") // トップレベルの要素のみ動的にimportする
}
]
});
参考